#include "GRay3.h"
#include "GMath.h"

namespace GMath
{

	GRay3::GRay3()
	{
		Origin = GVector3::Zero;
		Direction = GVector3::UnitZ;
	}

	GRay3::GRay3(const GVector3& Origin, const GVector3& Direction)
	{
		this->Origin = Origin;
		this->Direction = Direction;
	}

	void GRay3::Create(const GVector3& Origin, const GVector3& Direction)
	{
		this->Origin = Origin;
		this->Direction = Direction;
	}

	void GRay3::Reflect(GRay3& Output, float T, const GVector3& Normal) const
	{
		Output.Origin = FindPoint(T);
		Output.Direction = Normal * -Normal.Dot(Direction) * 2.0f;
	}

	bool GRay3::Refract(GRay3& Output, float T, const GVector3& Normal, float IndexEnter, float IndexLeave) const
	{
		float Nr = IndexEnter / IndexLeave;
		float CosI = -Normal.Dot(Direction);
		float CosT2 = 1.0f - Nr * Nr * CosI * CosI;

		if (CosT2 <= 0.0f)
		{
			return false;
		}

		Output.Origin = FindPoint(T);
		Output.Direction = (CosI - SqrtF(CosT2)) * Normal + Direction * Nr;
		Output.Direction.Normalize();

		return true;
	}

	GVector3 GRay3::FindPoint(float T) const
	{
		return Origin + Direction * T;
	}

}